﻿const padTwoDigits = value => (value < 10 ? `0${value}` : `${value}`);

const getCurrentDateString = () => {
  const now = new Date();
  const year = now.getFullYear();
  const month = padTwoDigits(now.getMonth() + 1);
  const day = padTwoDigits(now.getDate());
  return `${year}-${month}-${day}`;
};

const getCurrentTimeString = () => {
  const now = new Date();
  const hour = padTwoDigits(now.getHours());
  const minute = padTwoDigits(now.getMinutes());
  return `${hour}:${minute}`;
};

const combineDateTime = (datePart, timePart) => {
  if (!datePart || timePart === undefined || timePart === null || timePart === "") {
    return "";
  }
  return `${datePart} ${timePart}`;
};

const toISOStringString = value => {
  if (!value) {
    return "";
  }

  const [datePart, timePart = "00:00"] = value.split(" ");
  const [year, month, day] = datePart.split("-").map(Number);
  const [hour, minute] = timePart.split(":").map(Number);

  if (
    [year, month, day, hour, minute].some(num => Number.isNaN(num)) ||
    !year ||
    !month ||
    !day
  ) {
    return "";
  }

  const date = new Date(year, month - 1, day, hour, minute, 0);
  if (Number.isNaN(date.getTime())) {
    return "";
  }

  return date.toISOString();
};

const toDateObject = value => {
  if (!value) {
    return null;
  }

  const [datePart, timePart = "00:00"] = value.split(" ");
  const [year, month, day] = datePart.split("-").map(Number);
  const [hour, minute] = timePart.split(":").map(Number);

  if ([year, month, day, hour, minute].some(num => Number.isNaN(num))) {
    return null;
  }

  const date = new Date(year, month - 1, day, hour, minute, 0);
  return Number.isNaN(date.getTime()) ? null : date;
};

// 仅接受有限的整数，避免 1.5 这类非法人数通过校验
const parseNumberOrNull = value => {
  if (value === null || value === undefined || value === "") {
    return null;
  }
  const number = Number(value);
  if (!Number.isFinite(number) || !Number.isInteger(number)) {
    return null;
  }
  return number;
};

const showErrorToast = message => {
  wx.showToast({
    title: message,
    icon: "none"
  });
};

const createEmptyGroup = () => ({
  groupName: "",
  groupStartTime: "",
  groupStartTimeDate: "",
  groupStartTimeClock: "",
  groupEndTime: "",
  groupEndTimeDate: "",
  groupEndTimeClock: "",
  groupRegistrationCount: "",
  remark: ""
});

const createEmptyField = () => ({
  fieldName: "",
  isOptional: false
});

const createInitialActivity = () => ({
  activityName: "",
  activityLocation: "",
  registrationStartTime: "",
  registrationStartTimeDate: "",
  registrationStartTimeClock: "",
  registrationEndTime: "",
  registrationEndTimeDate: "",
  registrationEndTimeClock: "",
  activityDetails: "",
  activityImageURL: "",
  activityRequirements: ""
});

Page({
  data: {
    activity: createInitialActivity(),
    activityFields: [],
    groups: [createEmptyGroup()],
    submitting: false,
    defaultDate: getCurrentDateString(),
    defaultTime: getCurrentTimeString()
  },

  onShow() {
    this.setData({
      defaultDate: getCurrentDateString(),
      defaultTime: getCurrentTimeString()
    });
  },

  handleActivityInput(event) {
    const { field } = event.currentTarget.dataset;
    const { value } = event.detail;
    if (!field) {
      return;
    }
    this.setData({
      [`activity.${field}`]: value
    });
  },

  handleDateTimeChange(event) {
    const { field, part } = event.currentTarget.dataset;
    const { value } = event.detail;
    if (!field || !part) {
      return;
    }

    const dateKey = `${field}Date`;
    const timeKey = `${field}Clock`;
    const currentDate = this.data.activity[dateKey] || "";
    const currentTime = this.data.activity[timeKey] || "";
    const nextDate = part === "date" ? value : currentDate;
    const nextTime = part === "time" ? value : currentTime;
    const combined = combineDateTime(nextDate, nextTime);

    const updates = {};
    if (part === "date") {
      updates[`activity.${dateKey}`] = value;
    } else {
      updates[`activity.${timeKey}`] = value;
    }
    updates[`activity.${field}`] = combined;

    this.setData(updates);
  },

  handleChooseImage() {
    if (this.data.submitting) {
      return;
    }

    wx.chooseImage({
      count: 1,
      sizeType: ["compressed"],
      success: chooseRes => {
        const { tempFilePaths } = chooseRes;
        if (!tempFilePaths || tempFilePaths.length === 0) {
          return;
        }

        const filePath = tempFilePaths[0];
        const extensionMatch = filePath.match(/\.[^.]+$/);
        const extension = extensionMatch ? extensionMatch[0] : ".jpg";
        const cloudPath = `activities/${Date.now()}-${Math.random()
          .toString(36)
          .slice(2)}${extension}`;

        wx.showLoading({ title: "上传中", mask: true });
        wx.cloud.uploadFile({
          cloudPath,
          filePath,
          success: uploadRes => {
            this.setData({
              "activity.activityImageURL": uploadRes.fileID
            });
            wx.showToast({ title: "上传成功", icon: "success" });
          },
          fail: err => {
            console.error("活动图片上传失败", err);
            showErrorToast("上传失败，请重试");
          },
          complete: () => {
            wx.hideLoading();
          }
        });
      },
      fail: err => {
        if (err && err.errMsg && err.errMsg.includes("cancel")) {
          return;
        }
        showErrorToast("选择图片失败");
      }
    });
  },

  handlePreviewImage() {
    const url = this.data.activity.activityImageURL;
    if (!url) {
      return;
    }
    wx.previewImage({
      urls: [url]
    });
  },

  handleRemoveImage() {
    if (this.data.submitting) {
      return;
    }
    this.setData({
      "activity.activityImageURL": ""
    });
  },

  handleAddField() {
    this.setData({
      activityFields: this.data.activityFields.concat(createEmptyField())
    });
  },

  handleFieldInput(event) {
    const { index, field } = event.currentTarget.dataset;
    const { value } = event.detail;
    if (index === undefined || field === undefined) {
      return;
    }
    this.setData({
      [`activityFields[${index}].${field}`]: value
    });
  },

  handleFieldOptionalChange(event) {
    const { index } = event.currentTarget.dataset;
    const { value } = event.detail;
    if (index === undefined) {
      return;
    }
    this.setData({
      [`activityFields[${index}].isOptional`]: !!value
    });
  },

  handleRemoveField(event) {
    const { index } = event.currentTarget.dataset;
    if (index === undefined) {
      return;
    }
    const fields = this.data.activityFields.slice();
    fields.splice(index, 1);
    this.setData({
      activityFields: fields
    });
  },

  handleAddGroup() {
    this.setData({
      groups: this.data.groups.concat(createEmptyGroup())
    });
  },

  handleRemoveGroup(event) {
    const { index } = event.currentTarget.dataset;
    if (index === undefined || this.data.groups.length <= 1) {
      return;
    }
    const groups = this.data.groups.slice();
    groups.splice(index, 1);
    this.setData({
      groups
    });
  },

  handleGroupInput(event) {
    const { index, field } = event.currentTarget.dataset;
    const { value } = event.detail;
    if (index === undefined || field === undefined) {
      return;
    }
    this.setData({
      [`groups[${index}].${field}`]: value
    });
  },

  handleGroupDateTimeChange(event) {
    const { index, field, part } = event.currentTarget.dataset;
    const { value } = event.detail;
    if (index === undefined || field === undefined || !part) {
      return;
    }

    const group = this.data.groups[index];
    if (!group) {
      return;
    }

    const dateKey = `${field}Date`;
    const timeKey = `${field}Clock`;
    const currentDate = group[dateKey] || "";
    const currentTime = group[timeKey] || "";
    const nextDate = part === "date" ? value : currentDate;
    const nextTime = part === "time" ? value : currentTime;
    const combined = combineDateTime(nextDate, nextTime);

    const updates = {};
    if (part === "date") {
      updates[`groups[${index}].${dateKey}`] = value;
    } else {
      updates[`groups[${index}].${timeKey}`] = value;
    }
    updates[`groups[${index}].${field}`] = combined;

    this.setData(updates);
  },

  validateForPublish() {
    const { activity, groups, activityFields } = this.data;

    if (!activity.activityName.trim()) {
      return "请填写活动名称";
    }
    if (!activity.activityLocation.trim()) {
      return "请填写活动地点";
    }
    if (!activity.registrationStartTimeDate || !activity.registrationStartTimeClock) {
      return "请填写报名开始时间";
    }
    if (!activity.registrationEndTimeDate || !activity.registrationEndTimeClock) {
      return "请填写报名结束时间";
    }

    const registrationStartValue = combineDateTime(
      activity.registrationStartTimeDate,
      activity.registrationStartTimeClock
    );
    const registrationEndValue = combineDateTime(
      activity.registrationEndTimeDate,
      activity.registrationEndTimeClock
    );
    const registrationStart = toDateObject(registrationStartValue);
    const registrationEnd = toDateObject(registrationEndValue);

    if (!registrationStart || !registrationEnd) {
      return "报名时间格式不正确";
    }
    if (registrationStart.getTime() > registrationEnd.getTime()) {
      return "报名结束时间需晚于开始时间";
    }

    if (!activity.activityDetails.trim()) {
      return "请填写活动详细介绍";
    }
    if (!activity.activityImageURL) {
      return "请上传活动封面";
    }
    if (!activity.activityRequirements.trim()) {
      return "请填写活动要求";
    }
    if (!groups || groups.length === 0) {
      return "请至少创建一个活动分组";
    }

    const groupNames = new Set();

    for (let i = 0; i < groups.length; i += 1) {
      const group = groups[i];
      const displayIndex = i + 1;

      if (!group.groupName.trim()) {
        return `请填写第 ${displayIndex} 个分组的名称`;
      }
      const nameKey = group.groupName.trim();
      if (groupNames.has(nameKey)) {
        return `分组「${nameKey}」已存在，请修改名称`;
      }
      groupNames.add(nameKey);

      if (!group.groupStartTimeDate || !group.groupStartTimeClock) {
        return `请填写第 ${displayIndex} 个分组的活动开始时间`;
      }
      if (!group.groupEndTimeDate || !group.groupEndTimeClock) {
        return `请填写第 ${displayIndex} 个分组的活动结束时间`;
      }
      const startValue = combineDateTime(
        group.groupStartTimeDate,
        group.groupStartTimeClock
      );
      const endValue = combineDateTime(
        group.groupEndTimeDate,
        group.groupEndTimeClock
      );
      const startDate = toDateObject(startValue);
      const endDate = toDateObject(endValue);
      if (!startDate || !endDate) {
        return `第 ${displayIndex} 个分组的时间格式不正确`;
      }
      if (startDate.getTime() > endDate.getTime()) {
        return `第 ${displayIndex} 个分组的结束时间需晚于开始时间`;
      }

      const countValue = parseNumberOrNull(group.groupRegistrationCount);
      if (countValue === null || countValue <= 0) {
        return `请填写第 ${displayIndex} 个分组的有效报名人数上限`;
      }
    }

    if (activityFields.length > 0) {
      const fieldNames = [];
      for (let i = 0; i < activityFields.length; i += 1) {
        const field = activityFields[i];
        const trimmedName = field.fieldName.trim();
        if (!trimmedName) {
          return `请填写第 ${i + 1} 个报名问题的名称`;
        }
        if (fieldNames.includes(trimmedName)) {
          return `报名问题「${trimmedName}」重复，请修改`;
        }
        fieldNames.push(trimmedName);
      }
    }

    return "";
  },
  buildPayload(status) {
    const { activity, groups, activityFields } = this.data;

    const registrationStart = combineDateTime(
      activity.registrationStartTimeDate,
      activity.registrationStartTimeClock
    );
    const registrationEnd = combineDateTime(
      activity.registrationEndTimeDate,
      activity.registrationEndTimeClock
    );

    const payload = {
      activityName: activity.activityName.trim(),
      activityLocation: activity.activityLocation.trim(),
      activityDetails: activity.activityDetails.trim(),
      activityImageURL: activity.activityImageURL,
      activityRequirements: activity.activityRequirements.trim(),
      activityStatus: status,
      activityGroups: groups.map(group => {
        const start = combineDateTime(
          group.groupStartTimeDate,
          group.groupStartTimeClock
        );
        const end = combineDateTime(
          group.groupEndTimeDate,
          group.groupEndTimeClock
        );
        const count = parseNumberOrNull(group.groupRegistrationCount);

        const formatted = {
          groupName: group.groupName.trim(),
          remark: (group.remark || "").trim()
        };

        const startISO = toISOStringString(start);
        if (start && startISO) {
          formatted.groupStartTime = startISO;
        }

        const endISO = toISOStringString(end);
        if (end && endISO) {
          formatted.groupEndTime = endISO;
        }

        if (count !== null) {
          formatted.groupRegistrationCount = count;
        }

        return formatted;
      }),
      activityFields: activityFields.map(field => ({
        fieldName: field.fieldName.trim(),
        isOptional: !!field.isOptional
      }))
    };

    const startISO = toISOStringString(registrationStart);
    if (registrationStart && startISO) {
      payload.registrationStartTime = startISO;
    }

    const endISO = toISOStringString(registrationEnd);
    if (registrationEnd && endISO) {
      payload.registrationEndTime = endISO;
    }

    return payload;
  },

  handleSubmit(event) {
    const { status } = event.currentTarget.dataset;
    if (!status || this.data.submitting) {
      return;
    }

    if (status === "Published") {
      const validationMessage = this.validateForPublish();
      if (validationMessage) {
        showErrorToast(validationMessage);
        return;
      }
    }

    const payload = this.buildPayload(status);

    this.setData({ submitting: true });

    const app = getApp();
    const invoke =
      app && typeof app.callCloudFunction === "function"
        ? options => app.callCloudFunction(options)
        : options => {
            const { loadingTitle, ...rest } = options;
            const title =
              typeof loadingTitle === "string" && loadingTitle.trim()
                ? loadingTitle.trim()
                : "提交中...";
            wx.showLoading({ title, mask: true });
            const originalComplete = rest.complete;
            rest.complete = (...args) => {
              wx.hideLoading();
              if (typeof originalComplete === "function") {
                originalComplete(...args);
              }
            };
            return wx.cloud.callFunction(rest);
          };

    invoke({
      name: "createActivity",
      data: payload,
      loadingTitle: "提交中...",
      success: res => {
        const result = res && res.result ? res.result : res;
        if (result && result.success) {
          wx.showToast({
            title: "操作成功",
            icon: "success"
          });
          const createdActivityID =
            result.activityID || (result.data && result.data.activityID) || "";
          setTimeout(() => {
            this.navigateAfterCreate(createdActivityID);
          }, 800);
        } else {
          showErrorToast((result && result.error) || "操作失败，请稍后重试");
        }
      },
      fail: err => {
        console.error("createActivity 调用失败", err);
        showErrorToast("提交失败，请稍后重试");
      },
      complete: () => {
        this.setData({ submitting: false });
      }
    });
  },

  navigateAfterCreate(activityID) {
    const pages = typeof getCurrentPages === "function" ? getCurrentPages() : [];
    if (pages && pages.length > 1) {
      wx.navigateBack({ delta: 1 });
      return;
    }
    const targetId = activityID ? String(activityID).trim() : "";
    if (targetId) {
      wx.reLaunch({
        url: `/pages/activity-detail/activity-detail?activityID=${encodeURIComponent(
          targetId
        )}`
      });
      return;
    }
    wx.reLaunch({ url: "/pages/home/home" });
  }
});
